package com.avalon.core.select;

import com.avalon.core.alias.AbstractAliasSupport;
import com.avalon.core.condition.Condition;
import com.avalon.core.service.AbstractService;
import com.avalon.core.util.FieldUtils;
import com.avalon.core.util.ObjectUtils;
import com.avalon.core.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class TableFieldSectionList extends ArrayList<TableFieldSection> {


    public void addField(String field, AbstractService service) {
        TableFieldSection section = getTableFieldSection(field, service);

        section.addField(field);
    }

    private TableFieldSection getTableFieldSection(String field, AbstractService service) {
        TableFieldSection section = null;
        if (this.size() == 0) {
            section = new TableFieldSection(service);
            add(section);
        } else {
            for (TableFieldSection tableFieldSection : this) {
                if (tableFieldSection.isEqual(field)) {
                    section = tableFieldSection;
                    break;
                }
            }
            if (ObjectUtils.isNull(section)) {
                section = new TableFieldSection(service);
                add(section);
            }
        }
        return section;
    }

    public void addOrder(String field, String order, AbstractService service) {
        TableFieldSection section = getTableFieldSection(field, service);

        section.addOrder(field, order);
    }

    public void addOrder(OrderField orderField, AbstractService service) {
        TableFieldSection section = getTableFieldSection(orderField.getOriginField(), service);

        section.addOrder(orderField);
    }

    public void addCondition(ConditionField conditionField, AbstractService service) {
        TableFieldSection section = getTableFieldSection(conditionField.getOriginField(), service);

        section.addCondition(conditionField);
    }

    public String getConditionAlias(Condition condition, AbstractAliasSupport abstractAliasSupport) {
        for (TableFieldSection section : this) {
            if (section.isEqual(condition.getName())) {
                return section.getAlias(abstractAliasSupport);
            }
        }
        return null;
    }

    public String getOrderAlias(String fieldName, AbstractAliasSupport aliasSupport) {
        for (TableFieldSection section : this) {
            if (section.isEqual(fieldName)) {
                return section.getAlias(aliasSupport);
            }
        }
        return null;
    }

    public SelectionField getField(String fieldName, AbstractAliasSupport abstractAliasSupport) {
        for (TableFieldSection section : this) {
            if (section.containAlias(FieldUtils.getJoinFirstTableString(fieldName), abstractAliasSupport)) {
                return section.getField(fieldName);
            }
        }
        return null;
    }

    /**
     * 增加中间不存在字段的别名
     *
     * @param tableName
     * @param service
     */
    public void addTable(String tableName, AbstractService service) {
        TableFieldSection section = null;
        if (this.size() == 0) {
            section = new TableFieldSection(service);
            add(section);
        } else {
            for (TableFieldSection tableFieldSection : this) {
                if (StringUtils.isNotEmpty(tableFieldSection.getTableName()) &&
                        tableFieldSection.getTableName().equals(tableName)) {
                    return;
                }
            }
            if (ObjectUtils.isNull(section)) {
                section = new TableFieldSection(service);
                add(section);
            }
        }

        section.addTable(tableName);
    }

    private Boolean isComplete = false;

    /**
     * 补全所有关联表的别名
     */
    public void completeTable() {

        if (isComplete) return;
        while (true) {
            int oldCount = this.size();
            for (int i = 0; i < this.size(); i++) {
                TableFieldSection section = this.get(i);

                if (StringUtils.isEmpty(section.getTableName())) {//主表
                    continue;
                }

                Integer joinCount = FieldUtils.getJoinCount(section.getTableName());
                if (joinCount == 0) continue;// 只有一个表，不需要补全

                List<String> joinStringList = FieldUtils.getJoinStringList(section.getTableName());

                for (int i1 = 0; i1 < joinStringList.size() - 1; i1++) {
                    String joinString = FieldUtils.getJoinString(joinStringList, i1);

                    addTable(joinString, section.getService());
                }
            }
            if (oldCount == this.size()) {
                break;
            }
        }
        isComplete = true;

        sort((first, second) -> first.getJoinCount().compareTo(second.getJoinCount()));//排序保证小表在前
    }

    public String getPrefixTableAlias(String prefixTable, AbstractAliasSupport abstractAliasSupport) {

        for (TableFieldSection section : this) {
            if (StringUtils.isNotEmpty(section.getTableName()) &&
                    section.getTableName().equals(prefixTable)) {
                return section.getAlias(abstractAliasSupport);
            }
        }

        return null;
    }
}
